package com.gzj.environment.module.collectData.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.CharUtil;
import com.gzj.environment.enums.code.impl.collectDataCode.CollectDataCode;
import com.gzj.environment.framework.exception.CustomerException;
import com.gzj.environment.module.collectData.message.Message;
import com.gzj.environment.module.collectData.service.HandlerMessageService;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.DefaultFileRegion;
import io.netty.channel.FileRegion;
import io.netty.util.CharsetUtil;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@NoArgsConstructor
@Slf4j
public class HandlerMessageServiceImpl implements HandlerMessageService {

    private final Map<String, Message> messageMap = new HashMap<>();

    // 操作系统识别的换行符
    private static final String CR=System.getProperty("line.separator");

    @Autowired
    public HandlerMessageServiceImpl(List<Message> list) {
        if (CollectionUtil.isNotEmpty(list)) {
            for (Message message : list) {
                messageMap.put(message.messageType(), message);
            }
        }
    }

    /**
     * 处理消息的统一方法
     * @param messageType 消息类型
     * @param ctx netty客户端通道信息
     * @param message 消息内容
     */
    public void handle(String messageType, ChannelHandlerContext ctx, String message) {
        Message receivedMessage = messageMap.get(messageType);
        if (receivedMessage == null) {
            throw new CustomerException(CollectDataCode.HAS_NO_MESSAGE_HANDLER);
        }
        receivedMessage.handle(ctx, message);
    }

    /**
     * 处理文件上传
     * @param ctx     netty客户端通道信息
     * @param message 文件内容
     */
    @Override
    public void handleFile(ChannelHandlerContext ctx, String message) {
        File file = new File(message);
        if (file.exists()) {
            if (!file.isFile()) {
                // 写入换行符表示文件结束
                ctx.writeAndFlush("Not a file: " + file + CR);
                return;
            }
            // 换行符表示文件结尾
//            ctx.write(file + " " + file.length() + CR);
            RandomAccessFile randomAccessFile = null;
            try {
                randomAccessFile = new RandomAccessFile(message, "r");
                FileRegion region = new DefaultFileRegion(
                        randomAccessFile.getChannel(), 0, randomAccessFile.length());
                ctx.write(region);
                // 写入换行符表示文件结束
                ctx.writeAndFlush(CR);
            } catch (Exception e) {
                log.error("传输文件失败", e);
            } finally {
                if (randomAccessFile != null) {
                    try {
                        randomAccessFile.close();
                    } catch (IOException e) {
                        log.error("关闭文件时发生异常", e);
                    }
                }
            }
        } else {
            ctx.writeAndFlush("File not found: " + file + CR);
        }
    }
}
